package com.example.cameralib

import android.graphics.Bitmap
import android.graphics.Matrix
import android.graphics.RectF
import android.media.FaceDetector
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.util.Size
import android.view.Surface
import android.view.TextureView
import android.view.View
import com.camera.JYCamera
import com.camera.impl.CameraCallback
import com.camera.tools.CameraBitmapUtils
import com.example.baseutils.*
import com.example.baseutils.activity.BaseActivity
import com.example.baseutils.camera.VideoEncoder
import com.example.baseutils.showMyToast
import kotlin.concurrent.thread

abstract class CameraLibActivity : BaseActivity(), CameraCallback, FaceDetect.FaceDetectCallBack {
    private val TAG = "CameraLibActivity"
    private lateinit var jyCamera: JYCamera

    //    private val cameraId = MySharedPreferences.read(Constance.CAMERA_ID, 1)
    private val cameraId = 0

    //    private var rotate = MySharedPreferences.read(Constance.CAMERA_ROTATE, 0f)
    private var rotation = MySharedPreferences.read(Constance.CAMERA_ROTATE, Surface.ROTATION_270)
    private var photoRotate = MySharedPreferences.read(Constance.PHOTO_ROTATE, 0f)
    private val size = Size(640, 480)
    protected val handler: Handler = Handler(Looper.getMainLooper())
    abstract fun takeBitmap(bitmap: Bitmap)
    abstract fun getCameraShowView(): TextureView
    protected var preViewIng = false
    protected var faceDetectState = false
    private val textureView by lazy { getCameraShowView() }
    private var getBitampState = false
    private var recordState = false
    private var savePath = "false"
    private var videoEncoder: VideoEncoder? = null
    protected var faceDetect = FaceDetect()
    protected var showBitmap: Bitmap? = null

    //控制人俩识别
    public fun openFace(state: Boolean) {
        faceDetect.setCallBack(this)
        this.faceDetectState = state
    }

    override fun face(mFace: Array<out FaceDetector.Face>?, bitmap: Bitmap?) {
//        "mFace ${mFace?.size}".log(TAG)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initData()
    }

    private fun initData() {
        jyCamera = JYCamera.Builder(this).setCameraType(cameraId)
            .setCameraPreviewSize(size.width, size.height)
            .setCameraPictureSize(size.width, size.height)
            .setCameraCallback(this)
//            .setCameraRotation(rotate.toInt())
            .setTakeCallback { bytes, bitmap, i ->
                val newBitmap = CameraBitmapUtils.rotateBitmap(bitmap, photoRotate, true)
                takeBitmap(newBitmap)

            }.build()

    }

    override fun onStart() {
        super.onStart()
        Log.i(TAG, "onStart: ")
        if (preViewIng) {
            startPreview()
        }
    }

    override fun onStop() {
        super.onStop()
        Log.i(TAG, "onStop: ")
        jyCamera.doStopPreview()
        jyCamera.doStopCamera()
    }


    /*旋转画面*/
    private fun configureTextureViewTransform(viewWidth: Int, viewHeight: Int) {
        Log.i(TAG, "configureTextureViewTransform: " + windowManager.defaultDisplay.rotation)
        /*activity.getWindowManager().getDefaultDisplay().getRotation();*/
        val matrix = Matrix()
        val viewRect = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())
        val bufferRect = RectF(
            0f,
            0f, viewHeight.toFloat(), viewWidth.toFloat()
        )
        val centerX = viewRect.centerX()
        val centerY = viewRect.centerY()
        "centerX $centerX".log(TAG)
        "centerY $centerY".log(TAG)
        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY())
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL)
            val scale: Float = kotlin.math.max(
                viewHeight.toFloat() / viewHeight.toFloat(),
                viewWidth.toFloat() / viewWidth.toFloat()
            )
            matrix.postScale(scale, scale, centerX, centerY)
            matrix.postRotate((90 * (rotation - 2)).toFloat(), centerX, centerY)
        } else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180f, centerX, centerY)
        }
        textureView.setTransform(matrix)
    }

    override fun onDestroy() {
        Log.i(TAG, "onDestroy: ")
        jyCamera.doStopPreview()
        jyCamera.doStopCamera()
        videoEncoder?.release()
        faceDetect.release()
//        jyCamera.releaseAll()
        super.onDestroy()
    }

    //异步方式拍摄
    fun takePhoto(view: View) {
//        jyCamera.takePhoto()
        getBitampState = true
    }

    //异步方式拍摄
    fun takeFastPhoto() {
//        jyCamera.takePhoto()
        getBitampState = true
    }

    //录视频
    fun startRecord(): String {
        if (recordState)
            stopRecord()
        videoEncoder = VideoEncoder()
        val file = FileUtil.getVideoFile("record_video")
        videoEncoder?.init(file.absolutePath, size.width, size.height)
        recordState = true
        return file.path
    }

    //停止录视频
    fun stopRecord() {
        if (!recordState)
            return
        recordState = false
        videoEncoder?.release()
    }

    //同步方式拍摄
    fun takePhoto(path: String): Bitmap? {
        return jyCamera.takePicture(path)
    }

    fun mirror() {
        jyCamera.mirror()
    }

    fun rotate() {
        rotation += 1
        if (rotation >= 4)
            rotation = 0
        MySharedPreferences.save {
            putInt(Constance.CAMERA_ROTATE, rotation)
        }
        textureView.post {
            configureTextureViewTransform(textureView.width, textureView.height)
        }
        "预览旋转 $rotation".showMyToast(this)
    }

    fun photoRotate() {
        photoRotate += 90f
        if (photoRotate >= 360f)
            photoRotate = 0f
        MySharedPreferences.save {
            putFloat(Constance.PHOTO_ROTATE, photoRotate)
        }
        "图片旋转 $photoRotate".showMyToast(this)
    }

    fun stopPreview(view: View) {
        jyCamera.doStopCamera()
    }

    fun stopPreview() {
        preViewIng = false
        jyCamera.doStopPreview()
        jyCamera.doStopCamera()
    }

    fun startPreview(view: View) {
        try {
            //等待view绘制结束回调它的尺寸，进行旋转
            textureView.post {
                configureTextureViewTransform(textureView.width, textureView.height)
            }
            jyCamera.doStartPreview(cameraId, textureView)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun startPreview() {
        try {
            "startPreview".log(TAG)
            //等待view绘制结束回调它的尺寸，进行旋转
            textureView.post {
                configureTextureViewTransform(textureView.width, textureView.height)
            }
            jyCamera.doStartPreview(cameraId, textureView)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onOpenedCamera() {
        Log.i(TAG, "onOpenedCamera:  ${jyCamera.cameraResolutionList}")
        preViewIng = true
        textureView.setOnLongClickListener {
            rotate()
            true
        }
    }


    override fun onPreviewFrame(p0: ByteArray?, originBitmap: Bitmap?, p2: Int, p3: Int) {
        if (recordState)
            videoEncoder?.encode(p0, p2, p3)
        val bitmap = CameraBitmapUtils.rotateBitmap(originBitmap, photoRotate, true)
        //直接获取预览图片来保存
        synchronized(getBitampState) {
            try {
                //如果不拍照且打开了人脸识别
                if (!getBitampState && faceDetectState) {
                    faceDetect.detect(bitmap)
                    return
                }
                if (getBitampState) {
                    thread {
                        //压缩图片
                        takeBitmap(bitmap)
                    }
                } else {

                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                getBitampState = false
            }
        }

    }

    override fun onStopPreview() {
        Log.i(TAG, "onStopPreview: ")

    }

    override fun onClosedCamera() {
        Log.i(TAG, "onClosedCamera: ")
        stopRecord()
    }

}